package enemies 
{
	import entities.Entity;
	/**
	 * ...
	 * @author Gareth Williams
	 */
	public class RayPath implements IStrategyImplementation
	{
		private var timestepAtInstantiation:int;
		private var isInitialised:Boolean = false;
		private var xOffset:Number = 0;
		private var yOffset:Number = 0;
		
		public function RayPath()
		{
			timestepAtInstantiation = Main.timestep;
		}
		public function perform(on:Entity):Boolean
		{
			if (isInitialised == false)
			{
				xOffset = on.x;
				yOffset = on.y;
				isInitialised = true;
			}
			
			var tDelta:Number = Main.timestep - timestepAtInstantiation;
			var x:Number = on.rotation;
			var y:Number = on.rotation;
			var sin:Number = 0;
			var cos:Number = 0;
			
			//http://lab.polygonal.de/2007/07/18/fast-and-accurate-sinecosine-approximation/
			//always wrap input angle to -PI..PI
			if (y < -3.14159265)
				y += 6.28318531;
			else
			if (y >  3.14159265)
				y -= 6.28318531;
			
			//compute sine
			if (y < 0)
				sin = 1.27323954 * y + .405284735 * y * y;
			else
				sin = 1.27323954 * y - 0.405284735 * y * y;
			
			if (x < -3.14159265)
				x += 6.28318531;
			else
			if (x >  3.14159265)
				x -= 6.28318531;
			
			//compute cosine: sin(x + PI/2) = cos(x)
			x += 1.57079632;
			if (x >  3.14159265)
				x -= 6.28318531;
			
			if (x < 0)
				cos = 1.27323954 * x + 0.405284735 * x * x;
			else
				cos = 1.27323954 * x - 0.405284735 * x * x;
			
			//---------------------------------------------------------------------------------
			
			on.x = xOffset + cos * (tDelta * on.speed);
			on.y = yOffset + sin * (tDelta * on.speed);
			
			var isOutOfBounds:Boolean = false;
			if (on.x > Constants.SCREEN_WIDTH) isOutOfBounds = true;
			if (on.x < 0) isOutOfBounds = true;
			if (on.y > Constants.SCREEN_HEIGHT) isOutOfBounds = true;
			if (on.y < 0) isOutOfBounds = true;
			
			return isOutOfBounds;
		}
	}
}